package org.example.app.web.api.Impl;

import com.alibaba.fastjson.JSON;
import io.micrometer.common.util.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.app.model.BookKeep;
import org.example.app.model.Statistics;
import org.example.app.model.User;
import org.example.app.repository.BookKeepRepository;
import org.example.app.repository.UserRepository;
import org.example.app.service.BookKeepService;
import org.example.app.service.dto.BookKeepDto;
import org.example.app.service.dto.ReturnDto;
import org.example.app.service.util.JwtUtil;
import org.example.app.web.api.BookKeepController;
import org.example.app.web.vm.BookKeepVm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@RestController
@RequestMapping("/api")
public class BookKeepControllerImpl  implements BookKeepController {
    @Autowired
    BookKeepService bookKeepService;
    @Autowired
    BookKeepRepository bookKeepRepository;

    @Autowired
    private UserRepository userRepository;

    @Operation(summary = "添加账单")
    @PostMapping("/bookKeep")
    @Override
    public String create(@RequestBody BookKeepVm bookKeepVm,HttpServletRequest request) {
        //获取token
        String token = JwtUtil.getJwtFromRequest(request);
        //检查token是否传过来
        if(StringUtils.isBlank(token)){
            return JSON.toJSONString(new ReturnDto(-1,"非法请求",null));
        }
        //检查token是否传正确，是否是系统生成的令牌
        String userId = "";
        try {
            userId = JwtUtil.parseToken(token);
        }catch (Exception e){
            return JSON.toJSONString(new ReturnDto(-9,"token过期",null));
        }


        //校验必填字段
        if(bookKeepVm.getBookKeepDate() == null) {
            return JSON.toJSONString(new ReturnDto(-1,"日期必须传",null));
        }
        if(bookKeepVm.getType() == null) {
            return JSON.toJSONString(new ReturnDto(-1,"类型必须传",null));
        }
        if(StringUtils.isBlank(bookKeepVm.getCategory())){
            return JSON.toJSONString(new ReturnDto(-1,"分类必须传",null));
        }
        if(bookKeepVm.getPrice() == null){
            return JSON.toJSONString(new ReturnDto(-1,"价格必须传",null));
        }


        try {

            BookKeepDto bookKeepDto =bookKeepService.create(bookKeepVm, Integer.valueOf(userId));

            return JSON.toJSONString(new ReturnDto(1,"添加成功",bookKeepDto));

        } catch (Exception e) {
            return JSON.toJSONString(new ReturnDto(-99, "服务器内部错误", null));
        }
    }

    @Operation(summary = "获取当前用户全部账单")
    @GetMapping("/bookKeeps")
    public String getAccounts(HttpServletRequest request) {
        String token = JwtUtil.getJwtFromRequest(request);
        if(StringUtils.isBlank(token)){
            return JSON.toJSONString(new ReturnDto(-1,"非法请求",null));
        }

        String userId = "";
        try {
            userId = JwtUtil.parseToken(token);
        } catch (Exception e){
            return JSON.toJSONString(new ReturnDto(-9,"token过期",null));
        }
        Optional <User> userOptional = userRepository.findById(Integer.parseInt(userId));
         if (!userOptional.isPresent()){
             return JSON.toJSONString(new ReturnDto(-1,"不存在该用户",null));
         }

        List<BookKeepDto> bookKeepDtoList = bookKeepService.getAccount(userOptional.get());
        return JSON.toJSONString(new ReturnDto(1,"获取成功",bookKeepDtoList));
    }

    @Operation(summary = "删除账单")
    @DeleteMapping("/bookKeep/{id}")
    @Override
    public String delete(@PathVariable Integer id, HttpServletRequest request){
        //获取token
        String token = JwtUtil.getJwtFromRequest(request);
        //检查token是否传过来
        if(StringUtils.isBlank(token)){
            return JSON.toJSONString(new ReturnDto(-1,"非法请求",null));
        }
        //检查token是否传正确，是否是系统生成的令牌
        String userId = "";
        try {
            userId = JwtUtil.parseToken(token);
        }catch (Exception e){
            return JSON.toJSONString(new ReturnDto(-9,"token过期",null));
        }
        Optional<User> userOptional = userRepository.findById(Integer.parseInt(userId));
        if (!userOptional.isPresent()){
            return JSON.toJSONString(new ReturnDto(-1,"不存在该用户",null));
        }


        try {
            Optional<BookKeep> bookKeepOpt = bookKeepRepository.findByid(id);
            if ( !bookKeepOpt.isPresent()){
                return JSON.toJSONString(new ReturnDto(-1,"不存在该账单",null));
            }
            BookKeep bookKeep = bookKeepOpt.get();
            if (!bookKeep.getUser().getId().equals(Integer.parseInt(userId))){
                return JSON.toJSONString(new ReturnDto(-1,"无权限删除",null));
            }

            bookKeepService.deleteBookKeep(bookKeep);

            return JSON.toJSONString(new ReturnDto(1,"删除成功",null));
        } catch (Exception e) {
            return JSON.toJSONString(new ReturnDto(-1, "删除失败", null));
        }
    }

    @Operation(summary = "修改账单")
    @PutMapping("/bookKeep/{bookKeepId}")
    public String updateBookKeep(@PathVariable Integer bookKeepId,
                                 @RequestBody BookKeepVm bookKeepVm,
                                 HttpServletRequest request) {

        // 1. 获取 token
        String token = JwtUtil.getJwtFromRequest(request);
        if (StringUtils.isBlank(token)) {
            return JSON.toJSONString(new ReturnDto(-1, "非法请求", null));
        }

        // 2. 解析 token 获取 userId
        String userId;
        try {
            userId = JwtUtil.parseToken(token);
        } catch (Exception e) {
            return JSON.toJSONString(new ReturnDto(-9, "token过期", null));
        }

        // 3. 查询账单记录
        Optional<BookKeep> bookKeepOpt = bookKeepRepository.findByid(bookKeepId);
        if (!bookKeepOpt.isPresent()) {
            return JSON.toJSONString(new ReturnDto(-1, "账单不存在", null));
        }
        BookKeep bookKeep =  bookKeepOpt.get();


        // 4. 判断是否是当前用户的账单
        if (!bookKeep.getUser().getId().equals(Integer.valueOf(userId))) {
            return JSON.toJSONString(new ReturnDto(-1, "非法修改他人账单", null));
        }

        // 5. 校验必填字段
        if(bookKeepVm.getBookKeepDate() == null) {
            return JSON.toJSONString(new ReturnDto(-1,"日期必须传",null));
        }
        if(bookKeepVm.getType() == null) {
            return JSON.toJSONString(new ReturnDto(-1,"类型必须传",null));
        }
        if(StringUtils.isBlank(String.valueOf(bookKeepVm.getCategory()))){
            return JSON.toJSONString(new ReturnDto(-1,"分类不能为空",null));
        }
        if(bookKeepVm.getPrice() == null){
            return JSON.toJSONString(new ReturnDto(-1,"价格必须传",null));
        }

        // 6. 执行修改
        BookKeep updated = bookKeepService.update(bookKeep, bookKeepVm);

        // 7. 封装返回
        return JSON.toJSONString(new ReturnDto(1, "修改成功", new BookKeepDto(updated)));
    }

    @Operation(summary = "导出账单数据（按年或月）")
    @GetMapping("/bookKeep/export")
    @Override
    public void exportBookKeepData(@RequestParam(required = false) Integer year,
                                   @RequestParam(required = false) Integer month,
                                   HttpServletRequest request,
                                   HttpServletResponse response) {
//        System.out.println( "正在导出账单数据");

        String token = JwtUtil.getJwtFromRequest(request);
        if (StringUtils.isBlank(token)) {
//            System.out.println("token为空");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }

        String userId = "";
        try {
//            System.out.println("正在解析token");
            userId = JwtUtil.parseToken(token);
        } catch (Exception e) {
//             System.out.println("token解析失败");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }

        Optional<User> userOptional = userRepository.findById(Integer.parseInt(userId));
        if (!userOptional.isPresent()) {
//            System.out.println("用户不存在");
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        }

        List<BookKeepDto> data = bookKeepService.getFilteredBookKeeps(userOptional.get(), year, month);

        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("账单导出");

            Row header = sheet.createRow(0);
            header.createCell(0).setCellValue("账单ID");
            header.createCell(1).setCellValue("类型");
            header.createCell(2).setCellValue("分类");
            header.createCell(3).setCellValue("金额");
            header.createCell(4).setCellValue("备注");
            header.createCell(5).setCellValue("添加时间");

            int rowIdx = 1;
            for (BookKeepDto dto : data) {
                Row row = sheet.createRow(rowIdx++);
                row.createCell(0).setCellValue(dto.getBookKeepId());
                row.createCell(1).setCellValue(dto.getType() == 0 ? "支出" : "收入");
                row.createCell(2).setCellValue(dto.getCategory());
                row.createCell(3).setCellValue(dto.getPrice().toString());
                row.createCell(4).setCellValue(dto.getRemark());
                row.createCell(5).setCellValue(dto.getAddTime().toString());
            }

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = "账单导出_" + (year != null ? year : "全部") + (month != null ? "_" + month : "") + ".xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, StandardCharsets.UTF_8) + "\"");
//            System.out.println("导出成功");
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }

    }


    @Operation(summary = "获取收入与支出统计")
    @GetMapping("/bookkeep/statistics")
    public String getStatistics(HttpServletRequest request){
        //获取token
        String token = JwtUtil.getJwtFromRequest(request);
        //检查token是否传过来
        if(StringUtils.isBlank(token)){
            return JSON.toJSONString(new ReturnDto(-1,"非法请求",null));
        }
        //检查token是否传正确，是否是系统生成的令牌
        String userId = "";
        try {
            userId = JwtUtil.parseToken(token);
        }catch (Exception e){
            return JSON.toJSONString(new ReturnDto(-9,"token过期",null));
        }

        Integer id = Integer.valueOf(userId);
        Statistics statistics = bookKeepService.getStatistics(id);

        return JSON.toJSONString(new ReturnDto(1,"获取成功",statistics));


    }


}
